<?php
namespace app\client\controller;
use think\swoole\facade\Task;
use app\common\lib\GatewayCurl;
use app\common\lib\Redis;

class CardCharge {
    public function __construct() {
        
    }
    
    //线上卡
    public function chargeOnlineCard() {
        $params = request()->post();
        if(empty($params)) {
            return errorResult();
        }
        $data = [];
        $data['card_no'] = isset($params['card_no']) ? trim($params['card_no']) : '';
        $data['port_no'] = isset($params['port_no']) ? intval($params['port_no']) : 0;
        $sim = isset($params['sim']) ? trim($params['sim']) : '';
        $deviceId = !empty($params['device_id']) ? intval($params['device_id']) : -1;
        $data['charge_type'] = isset($params['charge_type']) ? intval($params['charge_type']) : 0;
        $data['charge_quantity'] = isset($params['charge_quantity']) ? intval($params['charge_quantity']) : 0;
        
        if($data['card_no'] === '' || $data['port_no'] <= 0 || $data['charge_quantity'] <= 0 || !in_array($data['charge_type'], [1, 2]) || $sim === '' || $deviceId < 0) {
           return errorResult();
        }
        
        unset($params);
        
        $deviceModel = model('Device');
        $cardModel = model('OnlineCard');
        $chargePriceModel = model('ChargePrice');
        $cardChargeOrderModel = model('CardChargeOrder');
        $agentModel = model('Agent');
        $storeModel = model('Store');
        Task::async(function() use(&$data, &$deviceId, &$sim, &$deviceModel, &$cardModel, &$chargePriceModel, &$cardChargeOrderModel, &$agentModel, &$storeModel) {
            $curl = new GatewayCurl();
            $repData = ['code' => 0, 'success' => false, 'deviceId' => $sim, 'portNo' => $data['port_no'], 'cardType' => 1, 'money' => 0, 'cardNo' => $data['card_no'], 'msg' => ''];

            $deviceFields = ['agent_id', 'store_id', 'device_no', 'price_id'];
            if($deviceId === 0) {
                array_push($deviceFields, 'device_id');
                $device = $deviceModel->findOne(['sim_iccid' => $sim], $deviceFields);
            }else {
                $device = $deviceModel->findOne(['device_id' => $deviceId], $deviceFields);
            }
            
            unset($deviceModel);
            if(empty($device)) {
                $repData['msg'] = '设备不存在';
                $curl->send('onlineCardCharge', $repData);
                
                return true;
            }
            
            if($deviceId === 0) {
                $deviceId = $device['device_id'];
            }
            

            $card = $cardModel->findOne(['card_no' => $data['card_no']], ['status', 'amount', 'card_id', 'user_id']);
            if(empty($card)) {
                $repData['code'] = 5;
                $repData['msg'] = '无效卡';
                $curl->send('onlineCardCharge', $repData); //无效卡
                
                return true;
            }
            
            if($card['status'] == 2) {
                $repData['code'] = 2;
                $repData['msg'] = '已挂失';
                $curl->send('onlineCardCharge', $repData); //已挂失
                
                return true;
            }
            
            if($card['status'] == -1) {
                $repData['code'] = 3;
                $repData['msg'] = '禁用';
                $curl->send('onlineCardCharge', $repData); //已禁用
                
                return true;
            }
            
            $price = $chargePriceModel->findOne(['price_id' => $device['price_id']], ['charge_type', 'charge_unit', 'class_rate', 'prepayment']);
            unset($chargePriceModel);
            if(empty($price) || $price['charge_type'] != $data['charge_type']) { //充电价格不存存在/计费模式不一致
                $repData['msg'] = '充电价格不存存在/计费模式不一致';
                $curl->send('onlineCardCharge', $repData);
                
                return true;
            }
            
            $classRate = $price['class_rate'];
            if(empty($classRate)) { //未设置费率
                $repData['msg'] = '未设置费率';
                $curl->send('onlineCardCharge', $repData);
                
                return true;
            }
            
            if(!is_array($classRate)) {
                $classRate = json_decode($classRate, true);
            }
            
            $baseRate = $classRate[count($classRate) - 1]; //以第四档费率为计费标准
            
            if($data['charge_type'] == 1) { //计时的
                $amount = roundNumber($price['prepayment'] / $baseRate['q'] * $data['charge_quantity'], 2);
            }else { //计量
                $data['charge_quantity'] = roundNumber($data['charge_quantity'] / 1000, 2); //度数
                $amount = roundNumber($baseRate['q'] * $data['charge_quantity'], 2);
            }
            
            if($amount > $card['amount']) { //余额不足
                $repData['code'] = 1;
                $repData['msg'] = '余额不足';
                $curl->send('onlineCardCharge', $repData);
                
                return true;
            }
            
            $data['status'] = 1;
            $data['amount'] = $amount;
            $data['user_id'] = $card['user_id'];
            $data['device_id'] = $deviceId;
            $data['device_no'] = $device['device_no'];
            $data['charge_unit'] = $price['charge_unit'];
            $data['start_time'] = time();
            
            if($device['agent_id'] > 0) {
                $data['agent_id'] = $device['agent_id'];
                $agent = $agentModel->findOne(['agent_id' => $data['agent_id']], ['agent_type']);
                if($agent['agent_type'] == 2) {
                    $data['pay_to'] = 2;
                }
                
                if($device['store_id'] > 0) {
                    $data['store_id'] = $device['store_id'];
                    $data['profit_rate'] = $storeModel->where(['store_id' => $data['store_id']])->value('profit_rate');
                }
            }
            
            
            $redis = new \app\common\lib\Redis();
            $cardModel->startTrans();
            
            try {
                $orderId = $cardChargeOrderModel->add($data);
                if(empty($orderId)) {
                    $cardModel->rollback();
                    $repData['msg'] = '加入订单失败';
                    $curl->send('onlineCardCharge', $repData);
                    
                    return true;
                }
                
                $rs = $cardModel->modify(['card_id' => $card['card_id']], ['amount' => $card['amount'] - $amount]);
                if(empty($rs)) {
                    $cardModel->rollback();
                    $repData['msg'] = '卡余额更改失败';
                    $curl->send('onlineCardCharge', $repData);
                    
                    return true;
                }
                
                try {
                    $redis->setex('online_card:' . $sim . ':' . $data['port_no'], $orderId, 3600 * 24);
                    $redis->close();
                } catch (\Exception $e) {
                }
                
                
                $repData['success'] = true;
                $repData['orderId'] = $orderId;
                $repData['money'] = ($card['amount'] - $amount) * 100;
                
                $result = $curl->send('onlineCardCharge', $repData);
                
                
                if($result['success'] == true) {
                    $cardModel->commit();
                }else{
                    $cardModel->rollback();
                }
                
            } catch (\Exception $e) {
                $cardModel->rollback();
                $curl->send('onlineCardCharge', $repData);
                
                
            }
            
            return true;
        });
        
        return successResult();
    }
    
    //线上卡增加充电
    public function addChargeOnlineCard() {
        $params = request()->post();
        if(empty($params)) {
            return errorResult();
        }
        $data = [];

        $data['card_no'] = isset($params['card_no']) ? trim($params['card_no']) : '';
        $data['port_no'] = isset($params['port_no']) ? intval($params['port_no']) : 0;
        $sim = isset($params['sim']) ? trim($params['sim']) : '';
        $deviceId = !empty($params['device_id']) ? intval($params['device_id']) : -1;
        $data['charge_type'] = isset($params['charge_type']) ? intval($params['charge_type']) : 0;
        $data['charge_quantity'] = isset($params['charge_quantity']) ? intval($params['charge_quantity']) : 0;
        $orderId = !empty($params['order_id']) ? intval($params['order_id']) : 0;
        
        if($orderId < 0 || $data['card_no'] === '' || $data['port_no'] <= 0 || $data['charge_quantity'] <= 0 || !in_array($data['charge_type'], [1, 2]) || $sim === '' || $deviceId < 0) {
            return errorResult();
        }

        $deviceModel = model('Device');
        $cardModel = model('OnlineCard');
        $chargePriceModel = model('ChargePrice');
        $cardChargeOrderModel = model('CardChargeOrder');

        if($orderId == 0){
            try {
                $redis = new Redis();
                $orderId = $redis->get('online_card:' . $sim . ':' . $data['port_no']);
                $redis->close();
            } catch (\Exception $e) {
            }
        }
        
        Task::async(function() use(&$data, &$sim, &$deviceId, &$orderId, &$deviceModel, &$cardModel, &$chargePriceModel, &$cardChargeOrderModel){
            $curl = new GatewayCurl();
            $repData = ['code' => 0, 'success' => false, 'deviceId' => $sim, 'portNo' => $data['port_no'], 'cardType' => 1, 'money' => 0, 'cardNo' => $data['card_no'], 'msg' => ''];
            
            $deviceFields = ['price_id'];
            if($deviceId === 0) {
                array_push($deviceFields, 'device_id');
                $device = $deviceModel->findOne(['sim_iccid' => $sim], $deviceFields);
            }else {
                $device = $deviceModel->findOne(['device_id' => $deviceId], $deviceFields);
            }
            
            unset($deviceModel);
            
            if(empty($device)) {
                $repData['msg'] = '设备不存在';
                $curl->send('onlineCardCharge', $repData);
                return true;
            }
            
            if($deviceId === 0) {
                $deviceId = $device['device_id'];
            }
            
            if(empty($orderId)) {
                $order = $cardChargeOrderModel->where(['device_id' => $deviceId, 'port_no' => $data['port_no'], 'card_no' => $data['card_no']])->field(['charge_quantity', 'charge_type', 'status', 'amount', 'order_id'])->order('order_id desc')->find();
            }else{
                $order = $cardChargeOrderModel->where(['order_id' => $orderId])->field(['charge_quantity', 'charge_type', 'status', 'amount'])->find();
            }
            
            if(empty($order) || $order['status'] != 1 || $order['charge_type'] != $data['charge_type']) {
                $repData['msg'] = '订单已完成或者付费方式不一致';
                $curl->send('onlineCardCharge', $repData);
                return true;
            }
            
            if(empty($orderId)) {
                $orderId = $order['order_id'];
            }
            
            $card = $cardModel->findOne(['card_no' => $data['card_no']], ['status', 'amount', 'card_id']);
            if(empty($card)) {
                $repData['code'] = 5;
                $curl->send('onlineCardCharge', $repData); //无效卡
                
                return true;
            }
            
            if($card['status'] == 2) {
                $repData['code'] = 2;
                $curl->send('onlineCardCharge', $repData); //已挂失
                
                return true;
            }
            
            if($card['status'] == -1) {
                $repData['code'] = 3;
                $curl->send('onlineCardCharge', $repData); //已禁用
                
                return true;
            }
            
            
            $price = $chargePriceModel->findOne(['price_id' => $device['price_id']], ['charge_type', 'class_rate', 'prepayment']);
            unset($chargePriceModel);
            if(empty($price) || $price['charge_type'] != $data['charge_type']) {
                $repData['msg'] = '价格不存在成或者付费方式不一致';
                $curl->send('onlineCardCharge', $repData);
                return true;
            }
            
            $classRate = $price['class_rate'];
            if(empty($classRate)) {
                $repData['msg'] = '费率空';
                $curl->send('onlineCardCharge', $repData);
                return true;
            }
            
            if(!is_array($classRate)) {
                $classRate = json_decode($classRate, true);
            }
            
            $baseRate = $classRate[count($classRate) - 1]; //取最后的
            
            if($data['charge_type'] == 1) { //计时的
                $amount = roundNumber($price['prepayment'] / $baseRate['q'] * $data['charge_quantity'], 2);
            }else { //计量
                $data['charge_quantity'] = roundNumber($data['charge_quantity'] / 1000, 2);
                $amount = roundNumber($baseRate['q'] * $data['charge_quantity'], 2);
            }
            
            if($amount > $card['amount']) { //余额不足
                $repData['code'] = 1;
                $curl->send('onlineCardCharge', $repData);
                return true;
            }
            
            $cardModel->startTrans();
            
            try {
                $rs = $cardChargeOrderModel->modify(['order_id' => $orderId], ['amount' => $order['amount'] + $amount, 'charge_quantity' => $order['charge_quantity'] + $data['charge_quantity']]);
                if(empty($rs)) {
                    $cardModel->rollback();
                    $repData['msg'] = $cardChargeOrderModel->getLastSql();
                    $curl->send('onlineCardCharge', $repData);
                    return true;
                }
                
                $rs = $cardModel->modify(['card_id' => $card['card_id']], ['amount' => $card['amount'] - $amount]);
                if(empty($rs)) {
                    $cardModel->rollback();
                    $repData['msg'] = $cardModel->getLastSql();
                    $curl->send('onlineCardCharge', $repData);
                    
                    return true;
                }

                $repData['success'] = true;
                $repData['money'] = ($card['amount'] - $amount) * 100;
                
                $result = $curl->send('onlineCardCharge', $repData);
                
                
                if($result['success'] == true) {
                    $cardModel->commit();
                }else{
                    $cardModel->rollback();
                }
                
                return true;
                
            } catch (\Exception $e) {
                $cardModel->rollback();
                $repData['msg'] = $e->getMessage();
                $curl->send('onlineCardCharge', $repData);
                
                return true;
            }
        });
        
       return successResult();
    }

    
    //查询余额
    public function balance() {
        $params = request()->post();
        if(empty($params)) {
            return errorResult();
        }
        
        $cardNo = isset($params['card_no']) ? trim($params['card_no']) : '';
        if($cardNo === '') {
            return errorResult();
        }
        
        $portNo = isset($params['port_no']) ? intval($params['port_no']) : 0;
        $sim = isset($params['sim']) ? trim($params['sim']) : '';
        
        $repData = ['code' => 0, 'success' => false, 'deviceId' => $sim, 'portNo' => $portNo, 'cardType' => 1, 'money' => 0, 'cardNo' => $cardNo, 'msg' => ''];
        
        $card = model('OnlineCard')->findOne(['card_no' => $cardNo], ['amount', 'status']);
        if(empty($card)) {//无效卡
            $repData['code'] = 5;
        }elseif($card['status'] == 2) {
            $repData['code'] = 2;
        }elseif($card['status'] == -1) {//已禁用
            $repData['code'] = 3;
        }else{
            $repData['success'] = true;
            $repData['money'] = $card['amount'] * 100;
        }
        
        
        $curl = new GatewayCurl();
        $curl->send('onlineCardCharge', $repData);
        
        return successResult();
    }
}










